﻿using H.Daos;
using H.Logs;
using H.Utils;
using HMaker.Dialogs;
using HMaker.Events;
using HModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace HMaker
{
    public partial class ResAllocator : Form
    {
        /// <summary>
        /// 数据访问对象实例
        /// </summary>
        private readonly IDao Dao;

        /// <summary>
        /// 日志输出实例
        /// </summary>
        private readonly ILog Log;

        /// <summary>
        /// 资源编辑器实例
        /// </summary>
        private readonly Lazy<ResEditor> _ResEditor = new Lazy<ResEditor>();



        protected ResAllocator()
        {
            InitializeComponent();
            RLV_Res.SelectObjectChanged += RLV_Res_SelectObjectChanged;
        }

        public ResAllocator(IDao dao, ILogCollector logCollector) : this()
        {
            Dao = dao;
            Log = logCollector.GetInstance("ResAllocator");
        }

        /// <summary>
        /// 加载资源类型
        /// </summary>
        private void LoadResType()
        {
            string[] types = Dao?.Query<ResEntity>()
                             .Distinct("type")
                             .Column<string>("type");
            CB_ResType.Items.Clear();
            if (types != null)
            {
                CB_ResType.Items.AddRange(types);
                if (CB_ResType.Items.Count > 0)
                {
                    CB_ResType.SelectedIndex = -1;
                    CB_ResType.SelectedIndex = 0;
                }
            }
        }

        /// <summary>
        /// 加载资源
        /// </summary>
        /// <param name="type"></param>
        private void LoadRes(string type)
        {
            ResEntity[] types = Dao?.Query<ResEntity>()
                            .Where("type", "=", type)
                            .Select();
            RLV_Res.ResetList(types);
        }


        /// <summary>
        /// 刷新图片组下拉选择框
        /// </summary>
        private void LoadImgGroup()
        {
            ImgGrpEntity[] groups = Dao?.Query<ImgGrpEntity>().Select();
            CB_ImgGroup.Items.Clear();
            if (groups != null)
            {
                CB_ImgGroup.Items.AddRange(groups);
                if (CB_ImgGroup.Items.Count > 0)
                {
                    CB_ImgGroup.SelectedIndex = -1;
                    CB_ImgGroup.SelectedIndex = 0;
                }
            }
        }

        /// <summary>
        /// 加载图片
        /// </summary>
        /// <param name="groupID"></param>
        private void LoadImgs(int? groupID)
        {
            IEnumerable<ImgEntity> imgs = Dao?.Query<ImgEntity>()
                                              .Where("group_id", "=", groupID)
                                              .Select();
            ILV_AllImg.ResetList(imgs);
        }

        /// <summary>
        /// 加载资源的图片
        /// </summary>
        private void LoadResImg(ResEntity entity)
        {
            if (entity != null)
            {
                TB_ResName.Text = entity.Type + " - " + entity.Name;
            }
            else
            {
                TB_ResName.Text = "";
            }
            if (!string.IsNullOrEmpty(entity?.ImgIds))
            {
                ImgEntity[] imgs = Dao?.Query<ImgEntity>().Where("id", "in", entity.ImgIds).Select();
                if (imgs != null)
                {
                    ILV_ResImg.ResetList(IDUtil.SplitInts(entity.ImgIds).Join(imgs, k => k, p => p.ID.Value, (k, v) => v).ToArray());
                    return;
                }
            }
            ILV_ResImg.ResetList(null);
        }

        /// <summary>
        /// 检查图片
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        private bool CheckImgOperate(ImgEntity img)
        {
            if (img == null || !img.ID.HasValue)
            {
                MessageBox.Show("指定了无效的图片");
                return false;
            }
            ResEntity curObject = RLV_Res.CurObject;
            if (curObject == null)
            {
                MessageBox.Show("请先选择要编辑的资源");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 将某张图片加入到当前编辑的资源中
        /// </summary>
        private void UseImg(ImgEntity img)
        {
            if (!CheckImgOperate(img))
            {
                return;
            }
            string imgID = img.ID.Value.ToString();
            ResEntity curObject = RLV_Res.CurObject;
            string newIds = IDUtil.AddID(curObject.ImgIds, imgID);
            if (curObject.ImgIds != newIds)
            {
                curObject.ImgIds = newIds;
                Dao.Save(curObject);
                LoadResImg(curObject);
            }
            else
            {
                MessageBox.Show("此图片已经被用于当前资源");
            }
        }

        /// <summary>
        /// 将某张图片从当前编辑的资源中舍去
        /// </summary>
        private void AbandonImg(ImgEntity img)
        {
            if (!CheckImgOperate(img))
            {
                return;
            }
            string imgID = img.ID.Value.ToString();
            ResEntity curObject = RLV_Res.CurObject;
            string newIds = IDUtil.RemoveID(curObject.ImgIds, imgID);
            if (curObject.ImgIds != newIds)
            {
                curObject.ImgIds = newIds;
                Dao.Save(curObject);
                LoadResImg(curObject);
            }
            else
            {
                MessageBox.Show("此图片不属于当前资源当前资源");
            }
        }


        /// <summary>
        /// 将指定图片置顶
        /// </summary>
        /// <param name="img"></param>
        private void OrderImgTop(ImgEntity img)
        {
            if (!CheckImgOperate(img))
            {
                return;
            }
            string imgID = img.ID.Value.ToString();
            ResEntity curObject = RLV_Res.CurObject;
            string newIds = IDUtil.TopID(curObject.ImgIds, imgID);
            if (curObject.ImgIds != newIds)
            {
                curObject.ImgIds = newIds;
                Dao.Save(curObject);
                LoadResImg(curObject);
            }
        }
        /// <summary>
        /// 将指定图片上移
        /// </summary>
        /// <param name="img"></param>
        private void OrderImgUp(ImgEntity img)
        {
            if (!CheckImgOperate(img))
            {
                return;
            }
            string imgID = img.ID.Value.ToString();
            ResEntity curObject = RLV_Res.CurObject;
            string newIds = IDUtil.UpID(curObject.ImgIds, imgID);
            if (curObject.ImgIds != newIds)
            {
                curObject.ImgIds = newIds;
                Dao.Save(curObject);
                LoadResImg(curObject);
            }
        }
        /// <summary>
        /// 将指定图片下移
        /// </summary>
        /// <param name="img"></param>
        private void OrderImgDown(ImgEntity img)
        {
            if (!CheckImgOperate(img))
            {
                return;
            }
            string imgID = img.ID.Value.ToString();
            ResEntity curObject = RLV_Res.CurObject;
            string newIds = IDUtil.DownID(curObject.ImgIds, imgID);
            if (curObject.ImgIds != newIds)
            {
                curObject.ImgIds = newIds;
                Dao.Save(curObject);
                LoadResImg(curObject);
            }
        }
        /// <summary>
        /// 将指定图片置顶
        /// </summary>
        /// <param name="img"></param>
        private void OrderImgBottom(ImgEntity img)
        {
            if (!CheckImgOperate(img))
            {
                return;
            }
            string imgID = img.ID.Value.ToString();
            ResEntity curObject = RLV_Res.CurObject;
            string newIds = IDUtil.BottomID(curObject.ImgIds, imgID);
            if (curObject.ImgIds != newIds)
            {
                curObject.ImgIds = newIds;
                Dao.Save(curObject);
                LoadResImg(curObject);
            }
        }

        #region 事件响应函数
        private void ResAllocator_Load(object sender, EventArgs e)
        {
            LoadImgGroup();
            LoadResType();
        }

        private void Bn_RefreshImgGroup_Click(object sender, EventArgs e)
        {
            LoadImgGroup();
        }

        private void CB_ImgGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            LoadImgs((CB_ImgGroup.SelectedItem as ImgGrpEntity)?.ID);
        }

        private void Bn_RefreshType_Click(object sender, EventArgs e)
        {
            LoadResType();
        }

        private void CB_ResType_SelectedIndexChanged(object sender, EventArgs e)
        {
            LoadRes(CB_ResType.SelectedItem as string);
        }

        private void TSMI_CreateRes_Click(object sender, EventArgs e)
        {
            ResEditor editor = _ResEditor.Value;
            editor.Res = new ResEntity() { Type = CB_ResType.SelectedItem as string };
            if (editor.ShowDialog() == DialogResult.OK)
            {
                Dao.Save(editor.Res, false);
                if (Equals(editor.Res.Type, CB_ResType.SelectedItem))
                {
                    LoadRes(editor.Res.Type);
                }
                else
                {
                    LoadResType();
                }
            }
        }

        private void TSMI_EditRes_Click(object sender, EventArgs e)
        {
            ResEditor editor = _ResEditor.Value;
            editor.Res = RLV_Res.CurObject.Clone() as ResEntity;
            if (editor.ShowDialog() == DialogResult.OK)
            {
                Dao.Save(editor.Res);
                if (Equals(editor.Res.Type, CB_ResType.SelectedItem))
                {
                    LoadRes(editor.Res.Type);
                }
                else
                {
                    LoadResType();
                }
            }
        }

        private void TSMI_DeleteRes_Click(object sender, EventArgs e)
        {
            ResEntity curObject = RLV_Res.CurObject;

            if (MessageBox.Show($"您是否确认删除{curObject.Name},一旦确认删除则无法恢复", "警告",
                MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
            {
                Dao.Delete(curObject);
            }
        }

        private void RLV_Res_SelectObjectChanged(object sender, SelectItemArgs<ResEntity> e)
        {
            LoadResImg(e.Item);
        }


        private void TSMI_UsePicture_Click(object sender, EventArgs e)
        {
            UseImg(ILV_AllImg.CurObject);
        }

        private void TSMI_AbandonImg_Click(object sender, EventArgs e)
        {
            AbandonImg(ILV_ResImg.CurObject);
        }


        private void TSMI_OrderTop_Click(object sender, EventArgs e)
        {
            OrderImgTop(ILV_ResImg.CurObject);
        }

        private void TSMI_OrderUp_Click(object sender, EventArgs e)
        {
            OrderImgUp(ILV_ResImg.CurObject);
        }

        private void TSMI_OrderDown_Click(object sender, EventArgs e)
        {
            OrderImgDown(ILV_ResImg.CurObject);
        }


        private void TSMI_OrderBottom_Click(object sender, EventArgs e)
        {
            OrderImgBottom(ILV_ResImg.CurObject);
        }

        #endregion

        private void CMS_Res_Opening(object sender, CancelEventArgs e)
        {
            bool hasLvi = RLV_Res.CurLVI != null;
            TSMI_EditRes.Enabled = TSMI_DeleteRes.Enabled = hasLvi;
        }

        private void CMS_AllImg_Opening(object sender, CancelEventArgs e)
        {
            if (ILV_AllImg.CurLVI == null)
            {
                e.Cancel = true;
            }
        }

        private void CMS_ResImg_Opening(object sender, CancelEventArgs e)
        {
            if (ILV_ResImg.CurLVI == null)
            {
                e.Cancel = true;
            }
        }
    }
}
